//
//  SSPerson.m
//  Secret Santa
//
//  Created by Andrew Cain on 12/10/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#include <stdlib.h>
#include <Message/NSMailDelivery.h>

#import "SSPerson.h"


@implementation SSPerson

- (void)awakeFromInsert
{
	[super awakeFromInsert];
	
	[self addCannotGiveToObject: self];
}	

- (NSString *)email 
{
    NSString * tmpValue;
    
    [self willAccessValueForKey: @"email"];
    tmpValue = [self primitiveValueForKey: @"email"];
    [self didAccessValueForKey: @"email"];
    
    return tmpValue;
}

- (void)setEmail:(NSString *)value 
{
    [self willChangeValueForKey: @"email"];
    [self setPrimitiveValue: value forKey: @"email"];
    [self didChangeValueForKey: @"email"];
}

/*- (BOOL)validateEmail: (id *)valueRef error:(NSError **)outError 
{
    // Insert custom validation logic here.
    return YES;
}*/

- (NSString *)name 
{
    NSString * tmpValue;
    
    [self willAccessValueForKey: @"name"];
    tmpValue = [self primitiveValueForKey: @"name"];
    [self didAccessValueForKey: @"name"];
    
    return tmpValue;
}

- (void)setName:(NSString *)value 
{
    [self willChangeValueForKey: @"name"];
    [self setPrimitiveValue: value forKey: @"name"];
    [self didChangeValueForKey: @"name"];
}

- (BOOL)validateName: (id *)valueRef error:(NSError **)outError 
{
    // Insert custom validation logic here.
    return YES;
}


- (void) addCannotGiveToObject: (SSPerson *)value 
{    
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    
    [self willChangeValueForKey:@"cannotGiveTo" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    
    [[self primitiveValueForKey: @"cannotGiveTo"] addObject: value];
    
    [self didChangeValueForKey:@"cannotGiveTo" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    
    [changedObjects release];
}

- (void)removeCannotGiveToObject:(SSPerson *)value 
{
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    
    [self willChangeValueForKey:@"cannotGiveTo" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    
    [[self primitiveValueForKey: @"cannotGiveTo"] removeObject: value];
	
    [self didChangeValueForKey:@"cannotGiveTo" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    
    [changedObjects release];
}


- (void)addCannotReceiveFromObject:(SSPerson *)value 
{    
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    
    [self willChangeValueForKey:@"cannotReceiveFrom" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    
    [[self primitiveValueForKey: @"cannotReceiveFrom"] addObject: value];
    
    [self didChangeValueForKey:@"cannotReceiveFrom" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
    
    [changedObjects release];
}

- (void)removeCannotReceiveFromObject:(SSPerson *)value 
{
    NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
    
    [self willChangeValueForKey:@"cannotReceiveFrom" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    
    [[self primitiveValueForKey: @"cannotReceiveFrom"] removeObject: value];
    
    [self didChangeValueForKey:@"cannotReceiveFrom" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
    
    [changedObjects release];
}



- (NSNumber *) cannotGiveCount
{
	return [NSNumber numberWithUnsignedInt:[[self primitiveValueForKey: @"cannotGiveTo"] count]];
}

- (SSPerson *)giveTo 
{
    id tmpObject;
    
    [self willAccessValueForKey: @"giveTo"];
    tmpObject = [self primitiveValueForKey: @"giveTo"];
    [self didAccessValueForKey: @"giveTo"];
    
    return tmpObject;
}

- (void)setGiveTo:(SSPerson *)value 
{
    [self willChangeValueForKey: @"giveTo"];
    [self setPrimitiveValue: value
                     forKey: @"giveTo"];
    [self didChangeValueForKey: @"giveTo"];
}


- (BOOL)validateGiveTo: (id *)valueRef error:(NSError **)outError 
{
    // Insert custom validation logic here.
    return YES;
}


- (SSChristmas *)myChristmas 
{
    id tmpObject;
    
    [self willAccessValueForKey: @"myChristmas"];
    tmpObject = [self primitiveValueForKey: @"myChristmas"];
    [self didAccessValueForKey: @"myChristmas"];
    
    return tmpObject;
}

- (void)setMyChristmas:(SSChristmas *)value 
{
    [self willChangeValueForKey: @"myChristmas"];
    [self setPrimitiveValue: value
                     forKey: @"myChristmas"];
    [self didChangeValueForKey: @"myChristmas"];
}


- (BOOL)validateMyChristmas: (id *)valueRef error:(NSError **)outError 
{
    // Insert custom validation logic here.
    return YES;
}

- (NSComparisonResult)compare:(SSPerson *)other
{
	return [[self cannotGiveCount] compare: [other cannotGiveCount]];
}


- (BOOL) findMatchFrom: (NSMutableArray *) availablePeople
{
	NSLog(@"finding Match for  %@", [self name]);
		  
	SSPerson *p;
	
	NSMutableSet *result = [NSMutableSet setWithArray: availablePeople];
	[result minusSet: [NSSet setWithArray: [[self primitiveValueForKey: @"cannotGiveTo"] allObjects]]];

	NSLog(@"%@ can choose from %d options", [self name], [result count]);

	
	if( [result count] > 0 )
	{
		int useIdx = rand() % [result count];
		
		p = [[result allObjects] objectAtIndex: useIdx];
		[availablePeople removeObject: p];
		[self setGiveTo: p];
		
		NSLog(@"%@ checking match with %@", [self name], [p name]);
		
		return YES;
	}
	
	return NO;
}

- (BOOL) sendEmailWithMessage: (NSString *) messageBase withTitle: (NSString *)title;
{
	NSAttributedString *body;
	NSMutableDictionary *headers;
	NSMutableString *temp = [NSMutableString stringWithString: messageBase];
	
	[temp replaceOccurrencesOfString: @"{name}" 
						  withString: [self name] 
							 options: NSCaseInsensitiveSearch
							   range: NSMakeRange(0, [temp length]) ];

	[temp replaceOccurrencesOfString: @"{receiver}" 
						  withString: [[self giveTo] name] 
							 options: NSCaseInsensitiveSearch
							   range: NSMakeRange(0, [temp length]) ];
	
	body = [[[NSAttributedString alloc] initWithString:temp] autorelease];
	
	headers = [NSMutableDictionary dictionary];
	
	[headers setObject: @"\"Secret Santa\" <macite@gmail.com>"
				forKey: @"From"];
	
	[headers setObject: [NSString stringWithFormat: @"\"%@\" <%@>", [self name], [self email]]
				forKey: @"To"];
	
	[headers setObject: [NSString stringWithFormat: @"Secret Santa - %@", title]
				forKey: @"Subject"];
	
	NSLog(@"Sending mail: body %@", body);
	
	BOOL success = [NSMailDelivery deliverMessage:body
										  headers:headers
										   format:NSASCIIMailFormat
										 protocol:nil];	
	
	NSLog(@"Mail send result - %d", success);
	
	return success;
}

- (void) deletePerson
{
	[[self managedObjectContext] deleteObject: self];
}

@end


